/*
<div id="app" style="color: red; font-size: 18;">
  app
  <div class="wrap">
    <span>姓名:{{testStr}}999999999</span>
  </div>
</div>
转为ast树
再转换为
  _c("div",
    { id: "app"
      style:{
        "color":"red",
        "font-size":"18"
      }
    },
    _v("app"),
    _c("div",
      { class:"wrap" },
      _c("span",
        _v("姓名:"+_s("testStr")+"999999999")
      )
    )
  )
 */
// 匹配 {{}}
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;
export function generate(ast) {
  const children = genChildren(ast);
  const code = `_c('${ast.tag}',${
    ast.attrs.length > 0 ? `${genProps(ast.attrs)}` : "undefined"
  }${children ? `,${children}` : ""})`;
  return code;
}
// 处理text {{}}
function gen(node) {
  // 如果是元素节点
  if (node.type === 1) {
    return generate(node);
    // 如果是文本节点
  } else if (node.type === 3) {
    let text = node.text;
    // 如果没有{{}} 是纯文本
    if (!defaultTagRE.test(text)) {
      return `_v(${JSON.stringify(text)})`;
    }
    let match,
      index,
      lastIndex = (defaultTagRE.lastIndex = 0),
      tokens = [];
    while ((match = defaultTagRE.exec(text))) {
      index = match.index;
      if (index > lastIndex) {
        tokens.push(JSON.stringify(text.slice(lastIndex, index)));
      }
      tokens.push(`_s(${match[1].trim()})`);
      lastIndex = index + match[0].length;
    }
    if (lastIndex < text.length) {
      tokens.push(JSON.stringify(text.slice(lastIndex)));
    }
    return `_v(${tokens.join("+")})`;
  }
}
// 组装children
function genChildren(ast) {
  const children = ast.children;
  if (children) {
    return children
      .map((child) => {
        return gen(child);
      })
      .join(",");
  }
}
// 组装attr属性
function genProps(attrs) {
  let attrStr = "";
  for (let i = 0; i < attrs.length; i++) {
    const attr = attrs[i];
    // 处理style style = "color: red; font-size: 18;"
    if (attr.name === "style") {
      let styleAttrs = {};
      attr.value.split(";").map((styleAttr) => {
        let [key, value] = styleAttr.split(":");
        styleAttrs[key] = value;
      });
      attr.value = styleAttrs;
    }
    attrStr += `${attr.name}:${JSON.stringify(attr.value)},`;
  }
  return `{${attrStr.slice(0, -1)}}`;
}
